// 产品接口，定义了产品的使用行为，所有具体产品类都需要实现此接口
interface Product {
    void use();
}

// 具体产品类A，实现了Product接口，提供了具体的产品使用逻辑
class ConcreteProductA implements Product {
    @Override
    public void use() {
        System.out.println("Using ConcreteProductA.");
    }
}

// 具体产品类B，实现了Product接口，提供了对应的产品使用逻辑
class ConcreteProductB implements Product {
    @Override
    public void use() {
        System.out.println("Using ConcreteProductB.");
    }
}

// 定义枚举来表示产品类型，相比使用字符串作为类型判断，更具类型安全性和可读性
enum ProductType {
    TYPE_A,
    TYPE_B
}

// 产品工厂类，负责根据给定的产品类型创建相应的产品对象
class ProductFactory {
    /**
     * 根据传入的产品类型枚举值，创建并返回对应的产品对象。
     * 如果传入的产品类型不被识别，将会抛出一个IllegalArgumentException异常。
     *
     * @param type 产品类型枚举值，指定要创建的产品类型
     * @return 对应的产品对象
     */
    public static Product createProduct(ProductType type) {
        Product product = null;
        switch (type) {
            case TYPE_A:
                product = new ConcreteProductA();
                break;
            case TYPE_B:
                product = new ConcreteProductB();
                break;
            default:
                // 如果传入的类型不在定义的枚举范围内，抛出异常并提示错误信息
                throw new IllegalArgumentException("Unrecognized product type: " + type);
        }
        return product;
    }
}

// 测试工厂模式的演示类
public class FactoryPatternDemo {
    public static void main(String[] args) {
        try {
            // 使用工厂创建产品A并调用其使用方法
            Product productA = ProductFactory.createProduct(ProductType.TYPE_A);
            productA.use();

            // 使用工厂创建产品B并调用其使用方法
            Product productB = ProductFactory.createProduct(ProductType.TYPE_B);
            productB.use();
        } catch (IllegalArgumentException e) {
            // 捕获并打印出工厂创建产品时可能出现的异常信息，便于排查问题
            System.err.println("Error in creating product: " + e.getMessage());
        }
    }
}